//! 消息处理器策略接口
//! 定义处理不同类型ISO8583消息的策略模式

use iso8583_rs::iso8583::iso_spec::IsoMsg;
use iso8583_rs::iso8583::IsoError;
use crate::services::ValidationService;

/// 消息处理结果
pub struct MessageHandleResult {
    pub response_msg: IsoMsg,
    pub success: bool,
}

/// 消息处理器策略trait
pub trait MessageHandler {
    /// 处理消息
    fn handle(
        &self,
        request_msg: &IsoMsg,
        raw_msg: &[u8],
        validation_service: &ValidationService,
    ) -> Result<MessageHandleResult, IsoError>;

    /// 获取支持的消息类型
    fn supported_message_type(&self) -> &'static str;
}

/// 消息处理器工厂
pub struct MessageHandlerFactory {
    handlers: std::collections::HashMap<String, Box<dyn MessageHandler + Send + Sync>>,
}

impl MessageHandlerFactory {
    /// 创建新的处理器工厂
    pub fn new() -> Self {
        Self {
            handlers: std::collections::HashMap::new(),
        }
    }

    /// 注册消息处理器
    pub fn register_handler(&mut self, handler: Box<dyn MessageHandler + Send + Sync>) {
        let msg_type = handler.supported_message_type().to_string();
        self.handlers.insert(msg_type, handler);
    }

    /// 获取消息处理器
    pub fn get_handler(&self, message_type: &str) -> Option<&Box<dyn MessageHandler + Send + Sync>> {
        self.handlers.get(message_type)
    }

    /// 处理消息
    pub fn handle_message(
        &self,
        message_type: &str,
        request_msg: &IsoMsg,
        raw_msg: &[u8],
        validation_service: &ValidationService,
    ) -> Result<MessageHandleResult, IsoError> {
        match self.get_handler(message_type) {
            Some(handler) => handler.handle(request_msg, raw_msg, validation_service),
            None => Err(IsoError {
                msg: format!("不支持的消息类型: {}", message_type),
            }),
        }
    }
}

impl Default for MessageHandlerFactory {
    fn default() -> Self {
        let mut factory = Self::new();
        
        // 注册默认处理器
        factory.register_handler(Box::new(crate::handlers::AuthHandler::new()));
        factory.register_handler(Box::new(crate::handlers::ReversalHandler::new()));
        
        factory
    }
}